package QianFeng11.DynamicProxyPattern;

/**
 * 动态代理
 * 所谓动态代理，即通过代理类: Proxy的代理， 接口和实现类之间可以不直接发生联系，而
 * 可以在运行期( Runtime)实现动态关联。
 * java动态代理主要是使用java.lang.reflect包中的两个类。
 *
 * InvocationHandler类
 * public Object invoke(Object obj,Method method,Object[] obs)
 * 其中第一个参数obj指的是代理类，method 是被代理的方法，obs是指被代理的方法的参数组。此方法由代理类来实现。
 *
 * Proxy类
 * protected Proxy(InvocationHandler h);
 * static Class getProxyClass(ClassLoader loader,Class[] interfaces);
 * static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);
 * 动态代理其实是在运行时生成class，所以，我们必须提供一组interface, 然后告诉他class已经
 * 实现了这些interface，而且在生成Proxy的时候，必须给他提供一个handler,让他来接管实际的工作。
 *
 * 类加载器原理分析与实现
 *
 * 1、类的加载过程
 * JVM将类加载过程分为三个步骤:装载(Load)，链接(Link) 和初始化(Initialize)
 *      链接又分为三个步骤：验证->准备->解析
 * 1)装载:查找并加载类的二进制数据;
 * 2)链接:
 *      验证:确保被加载类的正确性;
 *      准备:为类的静态变量分配内存，并将其初始化为默认值;
 *      解析:把类中的符号引用转换为直接引用;
 * 3)初始化:为类的静态变量赋予正确的初始值;
 *
 * 2、类的初始化,类什么时候才被初始化？
 *      1)创建类的实例，也就是new一个对象
 *      2)访问某个类或接口的静态变量，或者对该静态变量赋值
 *      3)调用类的静态方法
 *      4)反射(Class.forName("com.vince.Dog"))
 *      5)初始化一个类的子类(会首先初始化子类的父类)
 *      6) JVM启动时标明的启动类，即文件名和类名相同的那个类
 *
 * 3、类的加载:
 * 指的是将类的.Class文件中的二进制数据读入到内存中，将其放在运行时数据区的方法区内，
 * 然后在堆区创建一个这个类的java.lang.Class对象，用来封装类在方法区类的对象。
 **/

public class Test {

    public static void main(String[] args) {
        testProxy();
    }

    public static void testProxy() {
        CreateProxy createProxy = new CreateProxy();//用来创建代理对象的对象
        //Subject person = new Person();
        //Subject proxySubject = (Subject) createProxy.create(person);
        Hotel person2 = new Person();
        Hotel proxyHotel = (Hotel) createProxy.create(person2);
        //proxySubject.shopping();//invoke
        proxyHotel.reserve();
    }
}
